import { world, system, BlockPermutation } from "@minecraft/server";
system.beforeEvents.startup.subscribe(data => {
    data.blockComponentRegistry.registerCustomComponent('jurassic:scale_leaves_drops', {
        onPlayerDestroy: e => {
            const block = e.block
            const item = e.player.getComponent('equippable').getEquipment('Mainhand')
            const player = e.player
            if (item?.typeId == "minecraft:shears") {
                player.runCommandAsync('loot spawn ' + JSON.stringify(block.location.x) + ' ' + JSON.stringify(block.location.y + 1) + ' ' + JSON.stringify(block.location.z) + ' loot "blocks/scale/jurassic_scale_leaves"')
            }
            if (!(item?.typeId == "minecraft:shears")) {
                player.runCommandAsync('loot spawn ' + JSON.stringify(block.location.x) + ' ' + JSON.stringify(block.location.y + 1) + ' ' + JSON.stringify(block.location.z) + ' loot "blocks/scale/jurassic_scale_leaves_drop"')
            }

        },
    });
});

system.beforeEvents.startup.subscribe(data => {
    data.blockComponentRegistry.registerCustomComponent('jurassic:sigillaria_leaves_drops', {
        onPlayerDestroy: e => {
            const block = e.block
            const item = e.player.getComponent('equippable').getEquipment('Mainhand')
            const player = e.player
            if (item?.typeId == "minecraft:shears") {
                player.runCommandAsync('loot spawn ' + JSON.stringify(block.location.x) + ' ' + JSON.stringify(block.location.y + 1) + ' ' + JSON.stringify(block.location.z) + ' loot "blocks/sigillaria/jurassic_sigillaria_leaves"')
            }
            if (!(item?.typeId == "minecraft:shears")) {
                player.runCommandAsync('loot spawn ' + JSON.stringify(block.location.x) + ' ' + JSON.stringify(block.location.y + 1) + ' ' + JSON.stringify(block.location.z) + ' loot "blocks/sigillaria/jurassic_sigillaria_sapling"')
            }

        },
    });
});

// Allowed and leaf blocks combined into sets for quick lookups
const allowedBlocksSet = new Set([
    'jurassic:scale_log', 'jurassic:stripped_scale_log', 'jurassic:dried_scale_log', 'jurassic:stripped_dried_scale_log', 'jurassic:sigillaria_log'
]);

const leafBlocksSet = new Set([
    'jurassic:scale_leaves', 'jurassic:sigillaria_leaves'
]);

// Check if an allowed block is nearby within a 6-block radius
function isWithinRadiusOfAllowedBlock(block, maxDistance) {
    const { x: startX, y: startY, z: startZ } = block.location;
    for (let x = startX - maxDistance; x <= startX + maxDistance; x++) {
        for (let y = startY - maxDistance; y <= startY + maxDistance; y++) {
            for (let z = startZ - maxDistance; z <= startZ + maxDistance; z++) {
                const currentBlock = block.dimension.getBlock({ x, y, z });
                if (currentBlock && allowedBlocksSet.has(currentBlock.typeId)) {
                    const distance = Math.sqrt(Math.pow(x - startX, 2) + Math.pow(y - startY, 2) + Math.pow(z - startZ, 2));
                    if (distance <= maxDistance) return true;
                }
            }
        }
    }
    return false;
}

// Recalculate persistence for a block based on nearby allowed blocks
function recalculatePersistence(block) {
    const persistent = isWithinRadiusOfAllowedBlock(block, 9);
    const currentStates = block.permutation.getAllStates();
    const newStates = { ...currentStates, 'jurassic:persist': persistent };
    const newPermutation = BlockPermutation.resolve(block.typeId, newStates);
    block.setPermutation(newPermutation);

    if (!persistent && !block.permutation.getState('jurassic:placed')) {
        const { x, y, z } = block.location;
        try {
            drop_leaf_loot(block);
            block.dimension.runCommand(`/setblock ${x} ${y} ${z} air destroy`);
        } catch (error) {
            console.error("Failed to set block to air:", error);
        }
    }
}

function drop_leaf_loot(block) {
    //let num = Math.round(Math.random() * 2)
    let num = 0
    if (num < 1) {
        let num = Math.round(Math.random() * 4)
        const { x, y, z } = block.location;
        if (block.typeId == "jurassic:scale_leaves") {
            block.dimension.runCommand(`/loot spawn ${x} ${y} ${z} loot "blocks/scale/jurassic_scale_leaves"`);
        }
        if (block.typeId == "jurassic:sigillaria_leaves") {
            block.dimension.runCommand(`/loot spawn ${x} ${y} ${z} loot "blocks/sigillaria/jurassic_sigillaria_leaves"`);
        }
    }
}


// Register custom component for leaf decay
system.beforeEvents.startup.subscribe(eventData => {
    eventData.blockComponentRegistry.registerCustomComponent('jurassic:leaf_decay', {
        onRandomTick: (e) => {
            const { block } = e;
            if (leafBlocksSet.has(block.typeId)) recalculatePersistence(block);
        }
    });
});

// Handle player breaking blocks
world.afterEvents.playerBreakBlock.subscribe(eventData => {
    const { block } = eventData;
    if (allowedBlocksSet.has(block.typeId) || leafBlocksSet.has(block.typeId)) {
        recalculatePersistence(block);
    }
});

// Handle player placing blocks
world.afterEvents.playerPlaceBlock.subscribe(eventData => {
    const { block } = eventData;
    if (leafBlocksSet.has(block.typeId) && !block.permutation.getState('jurassic:placed')) {
        const currentStates = block.permutation.getAllStates();
        const newStates = { ...currentStates, 'jurassic:placed': true };
        const newPermutation = BlockPermutation.resolve(block.typeId, newStates);
        block.setPermutation(newPermutation);
    }
});

world.afterEvents.worldLoad.subscribe(drop_leaf_loot);
world.afterEvents.worldLoad.subscribe(recalculatePersistence);
world.afterEvents.worldLoad.subscribe(isWithinRadiusOfAllowedBlock);